/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.jili.ubert.server.publicdata;

import com.jili.ubert.code.ReturnIDEntity;
import com.jili.ubert.code.client2server.Login;
import com.jili.ubert.code.server2client.MsgResult;
import com.jili.ubert.dao.db.SafeForbidLogin;
import com.jili.ubert.dao.db.UserInfo;
import com.jili.ubert.server.datapool.DataPoolTrade;
import com.jili.ubert.server.resourcemanager.AESLock;
import io.netty.channel.Channel;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.avis.client.Elvin;
import org.avis.common.InvalidURIException;

/**
 *
 * @author ChengJiLi
 */
public class PublicData {

    private static Log log = LogFactory.getLog(PublicData.class);
    private DataPoolTrade datapool;
    private HashMap<String, UserInfo> usertable = new HashMap<>();
    private HashMap<String, OnlineUsers> onlineusertable = new HashMap<>();
    private HashMap<String, SafeForbidLogin> forbidUser = new HashMap<>();
    private Elvin elvintrade;
    private Elvin elvinprice;
    private Properties props;

    public PublicData() {
    }

    public PublicData(Properties props) {
        this.props = props;
        getTradeElvin();
        getPriceElvin();
    }
    //工作线程池
    private  ThreadPoolExecutor workExecutor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), 6, 1, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
    
    public void WorkRun(Runnable command){
        workExecutor.execute(command);
    }

    public UserInfo getUserInfo(String userid) {
        if (usertable.containsKey(userid)) {
            return usertable.get(userid);
        } else {
            UserInfo user = loadUserInfo(userid);
            usertable.put(userid, user);
            return user;
        }
    }

    private UserInfo loadUserInfo(String userid) {
        EntityManager em = datapool.getDBFactory().createEntityManager();
        Query queryuser = em.createNamedQuery("UserInfo.findByUserID", UserInfo.class);
        queryuser.setParameter(1, userid);
        UserInfo user = (UserInfo) queryuser.getSingleResult();
        return user;
    }
    private void loadFOrbidUser() {
        EntityManager em = datapool.getDBFactory().createEntityManager();
        Query queryuser = em.createNamedQuery("SafeForbidLogin.findAll", SafeForbidLogin.class);
        List<SafeForbidLogin> userls =  queryuser.getResultList();
        userls.stream().forEach((SafeForbidLogin o)->{forbidUser.put(o.getUserID().concat(o.getMac())+o.getId(), o);});
    }

    private OnlineUsers getOnlineUser(String userid) {
        if (onlineusertable.containsKey(userid)) {
            return onlineusertable.get(userid);
        } else {
            return null;
        }
    }

    public MsgResult Logout(String userID, int ip) {
        MsgResult rst = new MsgResult();
        /*
         1.在线用户去掉；连接关闭
         2.是否清除用户数据；清除
         */
        String key = userID + "_" + ip;
        if (onlineusertable.containsKey(key)) {
            this.onlineusertable.get(key).getChannel().close();
            this.onlineusertable.remove(key);
        }
        return rst;
    }

    public MsgResult LoginCheck(Login login, int ip, Channel channel) {
        MsgResult rst;
        /*
         1.是否有用户
         2.有密码是否正确
         3.正确后加入在线用户
         4.是否加载用户资源，需要加载
         */
        if (this.usertable.containsKey(login.getUserID())) {
            if (login.getPWD().equals(this.usertable.get(login.getUserID()).getPwd())) {
                OnlineUsers usr = new OnlineUsers();
                usr.setUserID(login.getUserID());
                usr.setIp4(ip);
                usr.setChannel(channel);
                this.onlineusertable.put(login.getUserID() + "_" + ip, usr);
                //加载资源
                //    this.LoginLoadAppMem(login.getUserID());

                rst = ReturnIDEntity.Success;
            } else {
                rst = ReturnIDEntity.incorrectPassWord;
            }

        } else {
            rst = ReturnIDEntity.noExistUser;
        }
        return rst;
    }

    public Elvin getAvisElvin(String ip, String port) {
        Elvin elvin = null;
        //    String elvinUri = System.getProperty("elvin", "elvin://" + ip + ":" + port);
        String elvinUri = System.getProperty("elvin", "elvin://" + ip);
        log.info("avis地址:" + elvinUri);
        try {
            elvin = new Elvin(elvinUri);
            log.info("启动连接avis router:" + elvinUri);
            //System.out.println("启动连接avis router:"+elvinUri);
            elvin.closeOnExit();
        } catch (InvalidURIException | IllegalArgumentException | IOException e) {
            log.info(e);
        }
        return elvin;
    }

    public Elvin getTradeElvin() {
        if (elvintrade == null) {
            log.info("TradeAvis配置文件：" + props.containsKey("Avis.Trade.IP") + "  " + props.getProperty("Avis.Trade.IP"));
            if (props.containsKey("Avis.Trade.IP") && props.containsKey("Avis.Trade.Port")) {
                elvintrade = getAvisElvin(props.getProperty("Avis.Trade.IP"), props.getProperty("Avis.Trade.Port"));
            } else {
                elvintrade = getAvisElvin("local", "2917");
            }
        }
        return elvintrade;
    }

    public Elvin getPriceElvin() {
        if (elvinprice==null) {
            log.info("PriceAvis配置文件：" + props.containsKey("Avis.Price.IP") + "  " + props.getProperty("Avis.Price.IP"));
            if (props.containsKey("Avis.Price.IP") && props.containsKey("Avis.Price.Port")) {
                elvinprice = getAvisElvin(props.getProperty("Avis.Price.IP"), props.getProperty("Avis.Price.Port"));
            } else {
                elvinprice = getAvisElvin("0.0.0.0", "2917");
            }
        }
        return elvinprice;
    }

    public HashMap<String, SafeForbidLogin> getForbidUser() {
        return forbidUser;
    }
    public String AESEncrypt(String content, String decryptKey) {
        return AESLock.encrypt(content, decryptKey);
    }
    public String AESDecrypt(String content, String decryptKey) {
        return AESLock.decrypt(content, decryptKey);
    }

    public void setDatapool(DataPoolTrade datapool) {
        this.datapool = datapool;
    }

    public void setProps(Properties props) {
        this.props = props;
    }
}
